package com.dianshang.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.dianshang.pojo.goods.Goods;
import com.dianshang.pojo.goods.Sku;
import com.dianshang.pojo.goods.Spu;
import com.dianshang.service.goods.CategoryService;
import com.dianshang.service.goods.SkuService;
import com.dianshang.service.goods.SpuService;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.io.File;
import java.io.PrintWriter;
import java.util.*;

/**
 * 详情模块
 */
@RestController
@RequestMapping("/detail")
@CrossOrigin // 解决跨域
public class DetailController {

    @Reference
    private SpuService spuService;

    @Reference
    private SkuService skuService;

    @Reference
    private CategoryService categoryService;

    /**
     * 方法一(创建模板引擎)：item.html必须在WEB-INF——>templates文件下
     */
    // 创建模板引擎
    @Autowired
    private TemplateEngine engine;

    // 方法二(准备文件)：
    @Value("${pagePath}")
    private String pagePath;

    /**
     * 前台传递参数到后端
     *      方式一：@RequestParam(默认格式) // ("/createDetailPage")、@RequestParam("spuId")、localhost:9102/detail/createDetailPage?spuId=10000004737200.do
     *      方式二：@PathVariable(rest风格,参数路径的一部分) // ("/createDetailPage/{spuId}")、@PathVariable("spuId")、localhost:9102/detail/createDetailPage/10000004737200.do
     *      方式三：@RequestBody(json格式的数据) // ("/createDetailPage")、@RequestBody、localhost:9102/detail/createDetailPage/spuId=10000004737200.do
     */
    @RequestMapping("/createDetailPage/{spuId}") // localhost:9102/detail/createDetailPage/10000004737200.do
    public void createDetailPage(@PathVariable("spuId") String spuId){
        // 生成SPU系列,对应的详情页面(SKU的详情页面)
        // 查询商品组合内容
        Goods goods = spuService.findGoodsById(spuId);
        // 查询SPU/SKU的内容
        Spu spu = goods.getSpu();
        List<Sku> skuList = goods.getSkuList();
        // 先做判断
        if (skuList == null || skuList.size() <= 0){
            return;
        }
        // 创建一个映射关系
        // key：规格选中的具体的值 value：页面地址
        HashMap<String,String> specUrlMap = new HashMap<>(); // 也可以是Map<String,String> specUrlMap = new HashMap<>();
        // 遍历SKU,生成详情页
        for (Sku sku : skuList) {
            if (sku.getStatus().equals("1")){ // 商品状态 1-正常，2-下架，3-删除
                // {'颜色':'红色','版本':'8GB+128GB'}--->{'版本':'8GB+128GB','颜色':'红色'}
                // 未排序json---Map---排序规则--->排好序的JSON
                specUrlMap.put(JSON.toJSONString(JSON.parseObject(sku.getSpec()),SerializerFeature.MapSortField),sku.getId()+".html");
            }
        }
        // 创建页面(每个SKU为一个页面)
        for (Sku sku : skuList) {
            /**
             * 根据模板+map进行渲染,并输出一个静态的页面
             */
            // 1、上下文
            Context context = new Context();
            // 创建数据模型
            Map<String,Object> map = new HashedMap();
            // 将查询到的SPU/SKU数据封装到map中
            map.put("spu", spu);
            map.put("sku", sku);
            // 将查询到的商品分类名称封装到map中
            String categoryName1 = categoryService.findById(spu.getCategory1Id()).getName();
            String categoryName2 = categoryService.findById(spu.getCategory2Id()).getName();
            String categoryName3 = categoryService.findById(spu.getCategory3Id()).getName();
            map.put("categoryName1",categoryName1);
            map.put("categoryName2",categoryName2);
            map.put("categoryName3",categoryName3);
            // 将查询到的商品的图片(spu+sku)封装到map中
            String[] spuImages = spu.getImages().split(",");
            String[] skuImages = sku.getImages().split(",");
            ArrayList<String> spuImagesList = new ArrayList<>(Arrays.asList(spuImages));
            ArrayList<String> skuImagesList = new ArrayList<>(Arrays.asList(skuImages));
            spuImagesList.addAll(skuImagesList);
            map.put("spuImagesList",spuImagesList);
            // 规格
            // SPU的选项
            // {"颜色":["金色","黑色","蓝色"],"版本":["6GB+64GB","6GB+128GB","8GB+128GB"]}
            // key：规格名称 value：规格的值选项
            Map<String,List<String>> specItems =(Map) JSON.parseObject(spu.getSpecItems()); // specItems：规格列表
            // SPU+SKU选中的规格值
            // "颜色"--->[{ text:“金色”,"choose":true},{ text:“黑色”,"choose":false},{ text:“蓝色”,"choose":false}}]
            Map<String,List<Map>> specItemsNew = new HashMap<>();
            // SKU的选项
            // {"颜色":“金色”,“版本”:“6GB+64GB”}
            // key：规格名称 value：规格的值选项
            Map skuSpec = JSON.parseObject(sku.getSpec()); // spec规格
            Set<String> specNames = specItems.keySet(); // 所有的规格名称：["颜色","版本"]
            for (String specName : specNames) { // 遍历所有的规格名称
                List<String> specValues = specItems.get(specName); // 当前规格名称对应的所有的值：["金色","黑色","蓝色"],["6GB+64GB","6GB+128GB","8GB+128GB"]
                List<Map> specMap = new ArrayList<>(); // 新的list 集合
                for (String specValue : specValues) { // 遍历所有当前规格名称对应的所有的值
                    Map specValueMap = new HashMap<>(); // 存放某个值的数据
                    // 将某个值的数据封装到specValueMap中
                    specValueMap.put("text", specValue);
                    if (skuSpec.get(specName).equals(specValue)){
                        specValueMap.put("choose", true);
                    }else {
                        specValueMap.put("choose", false);
                    }
                    // 每个规则值,需要设定对应的URL 金色,黑色,蓝色
                    // 组装当前规格的选项
                    Map skuDefaultSpec = JSON.parseObject(sku.getSpec()); // spec规格
                    skuDefaultSpec.put(specName, specValue);
                    specValueMap.put("url", specUrlMap.get(JSON.toJSONString(skuDefaultSpec,SerializerFeature.MapSortField)));
                    specMap.add(specValueMap);
                }
                specItemsNew.put(specName, specMap); // 替换原来规格名对应的值列表
            }
            map.put("specItems", specItemsNew); // 规格列表/SPU+SKU选中的规格值
            context.setVariables(map);
            // 2、准备文件
            // 方法一(准备文件)：
            File file = new File("F:/detail/" + sku.getId() + ".html");
            // 判断生成的静态页面所在的目录是否存在,不存在就创建
            if (!file.getParentFile().exists()){
                file.getParentFile().mkdirs();
            }
            // 方法二(准备文件)：
            // File file =new File(pagePath);
            // 判断生成的静态页面所在的目录是否存在,不存在就创建
            /* if (!file.exists()){
                file.mkdirs();
            } */
            // File dest =new File(file,sku.getId()+".html");
            /**
             * 方法二(创建模板引擎)：item.html必须在resources文件下
             */
            /* // 创建模板引擎
            TemplateEngine engine = new TemplateEngine();
            // 创建一个视图解析器
            ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver(); // 模板解析器
            resolver.setTemplateMode(TemplateMode.HTML); // 模板模型
            resolver.setSuffix(".html"); // 后缀
            engine.setTemplateResolver(resolver); */
            // 3、生成页面
            try {
                PrintWriter printWriter = new PrintWriter(file,"utf-8");
                engine.process("item",context,printWriter);
                System.out.println("生成页面："+sku.getId()+".html");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 将商品价格加载到缓存中
     */
    @GetMapping("/price") // http://localhost:9102/detail/price.do?skuId=100000047372
    public Integer findPriceByIdRedis(String skuId){
        return skuService.findPriceByIdRedis(skuId);
    }

}